//
// Created by wyh on 2025-06-16 19:42.
//

#ifndef TEST_UTILITY_LOGGER_H
#define TEST_UTILITY_LOGGER_H

#include <string>
#include <fstream>
#include <mutex>

namespace wyh {
    namespace utility {

#define log_debug(format,...)      Singleton<Logger>::instance()->log(Logger::LOG_DEBUG, __FILE__, __LINE__, format, ##__VA_ARGS__)
#define log_info(format,...)       Singleton<Logger>::instance()->log(Logger::LOG_INFO, __FILE__, __LINE__, format, ##__VA_ARGS__)
#define log_warn(format,...)       Singleton<Logger>::instance()->log(Logger::LOG_WARN, __FILE__, __LINE__, format, ##__VA_ARGS__)
#define log_error(format,...)      Singleton<Logger>::instance()->log(Logger::LOG_ERROR, __FILE__, __LINE__, format, ##__VA_ARGS__)
#define log_fatal(format,...)      Singleton<Logger>::instance()->log(Logger::LOG_FATAL, __FILE__, __LINE__, format, ##__VA_ARGS__)

        class Logger
        {
        public:
            enum Leval{
                LOG_DEBUG = 0,
                LOG_INFO,
                LOG_WARN,
                LOG_ERROR,
                LOG_FATAL,
                LOG_COUNT
            };

            void open(const std::string &filename);

            void close();

            void log(Leval leval, const char *file, int line, const char *format, ...);

            void set_leval(Leval leval);

            void set_max_size(int size);

            void set_console(bool console);

        private:
            void rotate();

            void localtime(struct tm *time_info, const time_t *ticks);

            void sleep(int milliseconds);

        private:
            std::string m_filename;
            std::ofstream m_ofs;
            bool m_console{true};
            int m_max{0};
            int m_len{0};
            int m_leval = LOG_DEBUG;
            static const char *s_leval[LOG_COUNT];

            std::mutex m_mutex;
        };
    } // namespace utility
} // namespace wyh

#endif //TEST_UTILITY_LOGGER_H
